<?php

/* esq 验证码 by xuanyan <njuxiahan@gmail.com> */

if (!defined('IN_ESQ'))
{
    die('Hacking attempt');
}

require_module_config('framework.captcha');

class cls_captcha
{
    // TODO 写本地文件要经常更新

    private static $_CFG = array();

    public static function out()
    {
        self::$_CFG = $GLOBALS['captcha_server_settings']['default'];

        if (isset(self::$_CFG['_img']))
        {
            self::generate_image();
        }
        elseif (isset(self::$_CFG['_text']))
        {
            self::generate_text();
        }
    }

    private static function record_word($word)
    {
        $GLOBALS['_SESSION']->captcha_word = $word;
    }

    private static function send_header($type)
    {
        esq_header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
        esq_header('Last-Modified: ' . http_date());
        esq_header('Cache-Control: private');

        if ($_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.0')
        {
            esq_header('Pragma: no-cache');
        }

        esq_header('Content-type: image/' . $type);
    }

    private static function gen_word($len)
    {
        $word = isset(self::$_CFG['_img']['word']) ? explode(',', self::$_CFG['_img']['word']) : range('A', 'Z');
        shuffle($word);
        return mb_substr(implode('', $word), 0, $len, 'UTF-8');
    }

    private static function generate_image()
    {
        if (rand(1, 100) <= self::$_CFG['local_read_percent'])
        {
            $id = REQUEST_TIME % self::$_CFG['max_save_count'];
            $captcha = self::file_get_captcha($id);

            if (empty($captcha) || empty($captcha['word']) || empty($captcha['content']))
            {
                $captcha = self::inner_generate_image();
            }
            else
            {
                self::record_word($captcha['word']);
            }
        }
        else
        {
            $captcha = self::inner_generate_image();
        }

        if (rand(1, 100) <= self::$_CFG['local_write_percent'])
        {
            $id = REQUEST_TIME % self::$_CFG['max_save_count'];
            self::file_put_captcha($id, $captcha);
        }

        self::send_header('gif');
        echo $captcha['content'];
    }

    private static function inner_generate_image()
    {
        require_library('framework.fastcgi');

        $letters = isset(self::$_CFG['_img']['len']) ? self::$_CFG['_img']['len'] : 4;
        $word = self::gen_word($letters);
        self::record_word($word);
        $theme_id = rand(0, count(self::$_CFG['_img']['themes']) - 1);
        $para = 'action=image_generate' . '&siteid=' . SITEID . '&word=' . $word . '&bg=' . self::$_CFG['_img']['themes'][$theme_id][0] . '&width=' . self::$_CFG['_img']['width'] . '&height=' . self::$_CFG['_img']['height'] . '&color[r]=' . self::$_CFG['_img']['themes'][$theme_id][1] . '&color[g]=' . self::$_CFG['_img']['themes'][$theme_id][2] . '&color[b]=' . self::$_CFG['_img']['themes'][$theme_id][3];
        $content = Fastcgi::get($GLOBALS['captcha_server_settings']['api_url'], $para);

        return array('word' => $word, 'content' => $content);
    }

    private static function file_get_captcha($captcha_id)
    {
        $file = self::$_CFG['captcha_file_path'] . '/' . intval($captcha_id / 100) . '/' . $captcha_id;
        $file_content = @file_get_contents($file);
        if (empty($file_content) || strlen($file_content) < 5)
        {
            return false;
        }

        $letters = isset(self::$_CFG['_img']['len']) ? self::$_CFG['_img']['len'] : 4;
        $word = substr($file_content, 0, $letters);
        $content = substr($file_content, 4);

        return array('word' => $word, 'content' => $content);
    }

    private static function file_put_captcha($captcha_id, $captcha)
    {
        if (empty($captcha['word']) || empty($captcha['content']))
        {
            return false;
        }

        $file = self::$_CFG['captcha_file_path'] . '/' . intval($captcha_id / 100) . '/' . $captcha_id;
        put_file($file, $captcha['word'] . $captcha['content']);

        return true;
    }

    /* 生成验证码 */
    private static function generate_text()
    {
        require_library('framework.fastcgi');

        $_theme = rand(0, count(self::$_CFG['_text']['themes']) - 1);
        $theme = self::$_CFG['_text']['themes'][$_theme];
        self::record_word($theme[1]);

        self::send_header('gif');

        $para = 'siteid=' . SITEID . '&action=generate_text&_theme=' . $_theme;
        echo Fastcgi::get($GLOBALS['captcha_server_settings']['api_url'], $para);
    }

    /**
     * $GLOBALS['SERVICE_CONFIG']['captcha'] = 1 表示验证码每次都显示并且验证
     * $GLOBALS['SERVICE_CONFIG']['captcha'] = 2 表示验证码第一次不出现,也不验证
     * 所以 $GLOBALS['_SESSION']->captcha_cont = 1 就不验证
     *
     * 并且在输出验证码的函数 @see captcha 上可以看出
     * $GLOBALS['_SESSION']->captcha_cont 只可能是 >= 1 的
     */
    public static function check_captcha($word = '')
    {
        if (empty($GLOBALS['SERVICE_CONFIG']['captcha'])) // 没有开启验证码验证
        {
            return true;
        }

        if ($GLOBALS['SERVICE_CONFIG']['captcha'] == 2)
        {
            if (!isset($GLOBALS['_SESSION']->captcha_cont))
            {
                $GLOBALS['_SESSION']->captcha_cont = 0;
            }

            if ($GLOBALS['_SESSION']->captcha_cont < 2)
            {
                return true;
            }
        }

        if (empty($GLOBALS['_SESSION']->captcha_word))
        {
            return false;
        }

        $captcha_word = strtolower(",{$GLOBALS['_SESSION']->captcha_word},");
        if (strpos($captcha_word, ',' . strtolower(trim($word)) . ',') === false)
        {
            return false;
        }
        else
        {
            $GLOBALS['_SESSION']->captcha_cont = 0;
            return true;
        }
    }
}

?>
